import { Accessor, createSignal, For, Setter, Signal } from "solid-js";
import { PinField } from "./PinField";

export interface PinProps {
    length?: number;
    type?: string;
    inputMode?:
    | "numeric"
    | "tel"
    | "text"
    | "none"
    | "url"
    | "email"
    | "decimal"
    | "search";
    onComplete?(pin: string, currentIndex: number): void;
    regexCriteria?: RegExp;
    disabled?: boolean;
    ref?: any;
}


export function Pin(props: PinProps) {
    const [currentIndex, setCurrentIndex] = createSignal(0);
    const regexCriteria = props.regexCriteria ?? /^[a-zA-Z0-9]+$/;
    const length = props.length ?? 4;
    const values = new Array(length);
    const arr = new Array(length).fill(0);
    const signals: Signal<string>[] = new Array(length);
    const setters: Setter<string>[] = new Array(length);
    arr.forEach((_, index) => {
        signals[index] = createSignal<string>("");
        const originSetter: Setter<string> = signals[index][1];
        setters[index] = originSetter;
        signals[index][1] = (v: any): any => {
            originSetter(v);
            onItemChange(v, index);
        };
    });
    const type = props.type ?? "numeric";

    const onItemChange = (v: string, index: number) => {
        values[index] = v;
        if (v.length === 1 && index < length) {
            setCurrentIndex(index + 1);
        }
        const pin = values.join("");
        if (pin.length === length) {
            props.onComplete && props.onComplete(pin, currentIndex());
        }
    };
    // backspace
    const onItemBackspace = (index: number) => {
        if (index > 0) {
            setCurrentIndex(index - 1);
        }
    };

    const onPaste = (value?: string) => {
        if (!value || value.length !== length) {
            setTimeout(() => {
                signals[0][1]('');
                setCurrentIndex(0);
            })
            return;
        }
        signals.forEach((signal: Signal<string>, index: number) => {
            signal[1](validate(value[index]));
        })
    };

    const validate = (value: string) => {
        if (type === "numeric") {
            const numCode = value.charCodeAt(0);
            const isInteger =
                numCode >= "0".charCodeAt(0) && numCode <= "9".charCodeAt(0);
            return isInteger ? value[0] : "";
        }
        if (regexCriteria.test(value)) {
            return type === 'password' ? value : value.toUpperCase();
        }

        return "";
    };

    const clear = () => {
        signals.forEach((signal: Signal<string>) => {
            signal[1]('');
        })
    }

    props.ref && props.ref({
        clear
    });

    return (
        <div class="cm-pin">
            <For each={arr}>
                {(_: number, index: Accessor<number>) => {
                    return (
                        <PinField
                            type={type}
                            disabled={props.disabled}
                            value={signals[index()]}
                            validate={validate}
                            inputMode={props.inputMode}
                            index={index()}
                            currentIndex={currentIndex()}
                            onChange={onItemChange}
                            onBackspace={onItemBackspace}
                            onPaste={index() === 0 ? onPaste : undefined}
                        />
                    );
                }}
            </For>
        </div>
    );
}
